/*
 * @Descripttion: 
 * @version: 
 * @Author: 玄绮 <shijiahansi@qq.com>
 * @Date: 2021-10-28 19:13:50
 * @LastEditTime: 2021-11-07 19:43:37
 * @LastEditors: VS Code
 */

#include <REG52.H>

#include "51_type.h"
#include "commom.h"

//定义独立按键控制脚
sbit KEY1 = const_P3 ^ 1;
sbit KEY2 = const_P3 ^ 0;
sbit KEY3 = const_P3 ^ 2;
sbit KEY4 = const_P3 ^ 3;

uint8 key_down_flag = 0;

//定义独立按键按下的键值
typedef enum
{
    KEY_UNPRESS,
    KEY1_PRESS,
    KEY2_PRESS,
    KEY3_PRESS,
    KEY4_PRESS
} KeyCode;

typedef enum
{
    Column1 = 0x07,
    Column2 = 0x0b,
    Column3 = 0x0d,
    Column4 = 0x0e,
    Row1 = 0x70,
    Row2 = 0xb0,
    Row3 = 0xd0,
    Row4 = 0xe0,
} KeyMatrix;

/**
 * @Author: 玄绮 <shijiahansi@qq.com>
 * @Date: 2021-10-29 22:53:29
 * @brief 检测独立按键是否按下，按下则返回对应键值 
 * @param {uint8}  mode=0：单次扫描按键
                   mode=1：连续扫描按键
 * @return {*}
 */
uint8 key_scan(uint8 mode)
{
    static uint8 key = 1;
    if (mode)
        key = 1;                                                        //连续扫描按键
    if (key == 1 && (KEY1 == 0 || KEY2 == 0 || KEY3 == 0 || KEY4 == 0)) //任意按键按下
    {
        delay_10us(1000); //消抖
        key = 0;
        if (KEY1 == 0)
            return KEY1_PRESS;
        else if (KEY2 == 0)
            return KEY2_PRESS;
        else if (KEY3 == 0)
            return KEY3_PRESS;
        else if (KEY4 == 0)
            return KEY4_PRESS;
    }
    else if (KEY1 == 1 && KEY2 == 1 && KEY3 == 1 && KEY4 == 1) //无按键按下
    {
        key = 1;
    }
    return KEY_UNPRESS;
}

#define KEY_MATRIX_PORT P1 //使用宏定义矩阵按键控制口

// /**
//  * @Author: 玄绮 <shijiahansi@qq.com>
//  * @Date: 2021-10-30 17:29:05
//  * @brief 使用行列式扫描方法，检测矩阵按键是否按下，按下则返回对应键值
//  * @param {*}
//  * @return key_value：1-16，对应 S1-S16 键，0：按键未按下
//  */
// uint8 key_matrix_ranks_scan(void)
// {
//     uint8 key_value = 0;
//     KEY_MATRIX_PORT = 0xf7; //给第一列赋值 0，其余全为 1

//     if (KEY_MATRIX_PORT != 0xf7) //判断第一列按键是否按下
//     {
//         delay_10us(1000);        //消抖
//         switch (KEY_MATRIX_PORT) //保存第一列按键按下后的键
//         {
//         case 0x77:
//             key_value = 1;
//             break;
//         case 0xb7:
//             key_value = 5;
//             break;
//         case 0xd7:
//             key_value = 9;
//             break;
//         case 0xe7:
//             key_value = 13;
//             break;
//         }
//     }
//     while (KEY_MATRIX_PORT != 0xf7)
//         ;                        //等待按键松开
//     KEY_MATRIX_PORT = 0xfb;      //给第二列赋值 0，其余全为 1
//     if (KEY_MATRIX_PORT != 0xfb) //判断第二列按键是否按下
//     {
//         delay_10us(1000);        //消抖
//         switch (KEY_MATRIX_PORT) //保存第二列按键按下后的键值
//         {
//         case 0x7b:
//             key_value = 2;
//             break;
//         case 0xbb:
//             key_value = 6;
//             break;
//         case 0xdb:
//             key_value = 10;
//             break;
//         case 0xeb:
//             key_value = 14;
//             break;
//         }
//     }
//     while (KEY_MATRIX_PORT != 0xfb)
//         ;                        //等待按键松开
//     KEY_MATRIX_PORT = 0xfd;      //给第三列赋值 0，其余全为 1
//     if (KEY_MATRIX_PORT != 0xfd) //判断第三列按键是否按下
//     {
//         delay_10us(1000);        //消抖
//         switch (KEY_MATRIX_PORT) //保存第三列按键按下后的键值
//         {
//         case 0x7d:
//             key_value = 3;
//             break;
//         case 0xbd:
//             key_value = 7;
//             break;
//         case 0xdd:
//             key_value = 11;
//             break;
//         case 0xed:
//             key_value = 15;
//             break;
//         }
//     }
//     while (KEY_MATRIX_PORT != 0xfd)
//         ;                        //等待按键松开
//     KEY_MATRIX_PORT = 0xfe;      //给第四列赋值 0，其余全为 1
//     if (KEY_MATRIX_PORT != 0xfe) //判断第四列按键是否按下
//     {
//         delay_10us(1000);        //消抖
//         switch (KEY_MATRIX_PORT) //保存第四列按键按下后的键值
//         {
//         case 0x7e:
//             key_value = 4;
//             break;
//         case 0xbe:
//             key_value = 8;
//             break;
//         case 0xde:
//             key_value = 12;
//             break;
//         case 0xee:
//             key_value = 16;
//             break;
//         }
//     }
//     while (KEY_MATRIX_PORT != 0xfe)
//         ; //等待按键松开
//     return key_value;
// }

/**
 * @Author: 玄绮 <shijiahansi@qq.com>
 * @Date: 2021-10-30 17:29:05
 * @brief 使用线翻转扫描方法，检测矩阵按键是否按下，按下则返回对应键值
 * @param {*}
 * @return key_value：1-16，对应 S1-S16 键，0：按键未按下
 */
uint8 key_matrix_flip_scan(void)
{
    static uint8 key_value = 0;
    KEY_MATRIX_PORT = 0x0f;                            //给所有行赋值 0，列全为 1
    if (KEY_MATRIX_PORT != 0x0f && key_down_flag == 0) //判断按键是否按下
    {
        delay_10us(100); //消抖
        if (KEY_MATRIX_PORT != 0x0f)
        {
            key_down_flag = 1;
            //测试列
            KEY_MATRIX_PORT = 0x0f;
            switch (KEY_MATRIX_PORT) //保存行为 0，按键按下后的列值
            {
            case 0x07:
                key_value = 1;
                break;
            case 0x0b:
                key_value = 2;
                break;
            case 0x0d:
                key_value = 3;
                break;
            case 0x0e:
                key_value = 4;
                break;
            }
            //测试行
            KEY_MATRIX_PORT = 0xf0;
            switch (KEY_MATRIX_PORT) //保存列为 0，按键按下后的键值
            {
            case 0x70:
                key_value += 0;
                break;
            case 0xb0:
                key_value += 4;
                break;
            case 0xd0:
                key_value += 8;
                break;
            case 0xe0:
                key_value += 12;
                break;
            }
            // while (KEY_MATRIX_PORT != 0xf0)
            //     ; //等待按键松开
        }
    }
    else
        key_value = 0;
    if (KEY_MATRIX_PORT == 0x0f)
        key_down_flag = 0;
    return key_value;
}